package com.kabuda.service.impl;

import com.alibaba.druid.wall.violation.ErrorCode;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kabuda.domain.User;
import com.kabuda.exception.LoginException;
import com.kabuda.exception.MyState;
import com.kabuda.service.UserService;
import com.kabuda.mapper.UserMapper;
import com.kabuda.utils.JWTUtils;
import com.kabuda.utils.R;
import org.apache.commons.codec.digest.Md5Crypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import springfox.documentation.spring.web.json.Json;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author kabuda
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2023-10-17 21:02:37
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    //盐值以$1$开头
    private static final String slat = "$1$dabuka";
    //private static final String slat = "mszlu!@###";

    @Override
    public Map<String, Object> login(User user) {
        String account = user.getAccount();
        String password = user.getPassword();
        //1.检查参数是否为空，为空登录失败
        if (!StringUtils.hasText(account) || !StringUtils.hasText(password)) {
            throw new  LoginException(MyState.PARAMETER_FAIL.getCode(),MyState.PARAMETER_FAIL.getMsg());
        }
        //2.根据参数查询数据库是否存在，不存在登录失败
        //数据库密码使用md5盐值加密了，我们加密再进行比对
        String passwordMD5 = Md5Crypt.md5Crypt(password.getBytes(), slat);
        User curUser = this.findUser(account, passwordMD5);
        if (curUser == null) {
            throw new  LoginException(MyState.PASSWORD_FAIL.getCode(),MyState.PASSWORD_FAIL.getMsg());
        }else{
            //记住密码

        }

        //3.如果存在，使用jwt生成woken返回给前端（前端根据返回的token，在发送获取登录信息的时候携带）
        String token = JWTUtils.createToken(curUser.getId());
        // 也可以不做该功能
        //4.redis存储token 设置一天过期时间，过期需要从重新登录才能获取信息（相当于session）
        //（获取登录信息时，前端传递过来的token会比对redis里面的token，成功则根据token获取playload信息）
        redisTemplate.opsForValue().set("token:" + token, JSON.toJSONString(curUser),  1, TimeUnit.DAYS);


        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        curUser.setPassword("");
        map.put("user", curUser);
        return map;
    }

    @Override
    public User findUser(String account, String passwordMD5) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getAccount,account);
        wrapper.eq(User::getPassword,passwordMD5);
        User user = this.baseMapper.selectOne(wrapper);
        return user;
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete("token:"+token);
    }

    @Override
    public User curUserInfo(String token) {
        Map<String, Object> map = JWTUtils.checkToken(token);
        String userId = (String) map.get("userId");
        User user = this.baseMapper.selectById(userId);
        user.setPassword("");
        return user;
    }
}





